import Taro from '@tarojs/taro'
import { HTTP_STATUS } from '../constants/status'
import { logError } from '@/utils/error'
import { API_URL, BASE_URL } from '@/constants/api'
import { refreshToken } from './refreshToken'

const apiRequest = {
  baseOptions(params, method: keyof Taro.request.Method = "GET", paramsOptions: any = {}) {
    let self = this;
    let { url, data } = params;
    let contentType = 'application/json';
    let options = {
      isShowErrorInfo: paramsOptions.isShowErrorInfo !== undefined ? paramsOptions.isShowErrorInfo : true,
      isResponseBody: paramsOptions.isResponseBody !== undefined ? paramsOptions.isResponseBody : false,
      isShowLoading: paramsOptions.isShowLoading !== undefined ? paramsOptions.isShowLoading : true,
      loadingText: paramsOptions.loadingText !== undefined ? paramsOptions.loadingText : "加载中...",
      delay:  paramsOptions.delay !== undefined ? paramsOptions.delay : 300,
    }
    type OptionType = {
      url: string,
      data?: object | string,
      method?: any,
      header: object,
      mode: string,
      success: any,
      fail: any,
      xhrFields: object,
    }
    let timer;
    data = {
      ...data,
      // timestamp: new Date().getTime(),
      // terminalType: getTerminalType(),
    }
    if (options.isShowLoading && !timer) {
      timer = setTimeout(() => {
        Taro.showLoading({
          title: options.loadingText,
        });
      }, options.delay)
    }
    return new Promise((resolve, reject) => {
      Taro.request<OptionType>({
        url: (url && url.includes("http")) ? url : `${API_URL}${BASE_URL}${url}`,
        data,
        method,
        header: {
          'content-type': contentType,
          'authorization': Taro.getStorageSync('User-Token'),
        },
        mode: 'cors',
        // xhrFields: { withCredentials: true },
        success(res: any) {
          console.log(res);                       
          
          if (res.statusCode === HTTP_STATUS.NOT_FOUND) {
            logError('api', '请求资源不存在')
            reject("error")
          } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
            logError('api', '服务端出现了问题')
            reject("error")
          } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
            logError('api', '没有权限访问')
            reject("error")
          } else if (res.statusCode === HTTP_STATUS.AUTHENTICATE) {
            // Taro.clearStorage()
            // Taro.navigateTo({
            //   url: '/pages/login/index'
            // })
            refreshToken(() => {
              let res = self.baseOptions(params, method);
              resolve(res); // 这里的resolve主要是将当前作用域返回的数据返回给外层，没有这行代码，组件中的awwait不会执行；
            });
            
            // logError('api', '请先登录')
            // reject("error")
          } else if (res.statusCode === HTTP_STATUS.CLIENT_ERROR) {
            logError('api', '请求参数有误')
            reject("error")
          } else if (res.statusCode === HTTP_STATUS.SUCCESS) {
            if (options.isResponseBody) {
              resolve(res.data)
              return
            }
            if (res.data && res.data.result === false) {
              logError('api', res.data.msg)
              reject("error")
              return
            }
            if (res.data && res.data.data) {
              resolve(res.data.data)
              return
            }
            resolve(res.data)
          } else {
            logError('api', '未知错误')
            reject("error")
          }
        },
        fail(e) {
          logError('api', '请求接口出现问题', e.toString())
          reject("error")
        },
        complete() {
          clearTimeout(timer);
          timer = undefined;
          Taro.hideLoading();
        }
      })
    })
  },
  get(url, data?: object, options?: any) {
    let option = { url, data }
    return this.baseOptions(option, 'GET', options)
  },
  post(url, data?: object, options?: any) {
    let params = { url, data }
    return this.baseOptions(params, 'POST', options)
  },
  put(url, data?: object, options?: any) {
    let option = { url, data }
    return this.baseOptions(option, 'PUT', options)
  },
  delete(url, data?: object, options?: any) {
    let option = { url, data }
    return this.baseOptions(option, 'DELETE', options)
  }
}

export default apiRequest;